package com.zj.base.base_act;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.FrameLayout;

import com.zj.base.LayoutModule;
import com.zj.base.view_injector.ViewBinder;
import com.zj.base.views.BaseLoadingView;
import com.zj.base.views.BaseLoadingView.DisplayMode;
import com.zj.base.R;
import com.zj.base.permission.ConfigurationModules;
import com.zj.base.permission.PermissionTools;
import com.zj.base.permission.interfaces.OnPermissionCheckListener;
import com.zj.base.utils.ToastUtils;
import com.zj.base.views.BaseTitleView;

import java.lang.ref.WeakReference;
import java.util.List;
import java.util.Map;

/**
 * Created by zhaojie on 2017/10/11.
 */

@SuppressWarnings("unused")
public abstract class BaseActivity extends AppCompatActivity {

    /**
     * rootView
     */
    private View contentView;
    public View rootView, titleLine;
    private BaseLoadingView blvLoading;
    private FrameLayout flContent;
    private BaseTitleView baseTitleView;
    protected Animation enter, exit;
    private ResumeHandler handler;
    private PermissionTools permissionTools;
    protected WeakReference<BaseActivity> weakReference;
    private static final int MSG_PERMISSION = 0x01a9;

    private Lifecycle lifecycle;

    private enum Lifecycle {
        RESUME, PAUSE, STOP, DESTROY, START, CREATE
    }

    protected abstract String setTitle();

    protected abstract LayoutModule getContentView();

    public abstract void initView();

    public abstract void initListener();

    protected void callRefresh() {
        hint(DisplayMode.loading, "正在重试，请稍候...", false);
    }

    /**
     * Setting the visibility of the line below the title bar
     */
    protected boolean isTitleLineShow() {
        return true;
    }

    protected boolean isTitleBarShow() {
        return true;
    }

    protected void setTitleBarVisibility(boolean isShow) {
        initTitleBar(isShow);
    }

    public BaseTitleView getBaseTitleView() {
        return baseTitleView;
    }

    protected void setTitle(String s) {
        baseTitleView.setTitle(s + "");
    }

    public boolean isEnableLeftToBack() {
        return true;
    }

    public BaseLoadingView getBlvLoading() {
        return blvLoading;
    }

    /**
     * 设置显示模式,可在主／非主线程调用
     */
    public void hint(final BaseLoadingView.DisplayMode mode, final String hint, final boolean showingOnActive) {
        if (Looper.myLooper() == Looper.getMainLooper()) {
            blvLoading.setMode(mode, hint, showingOnActive);
        } else {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    blvLoading.setMode(mode, hint, showingOnActive);
                }
            });
        }
    }

    /**
     * 获取一个弱引用的实例
     */
    protected WeakReference<BaseActivity> getWeakContext() {
        if (weakReference == null) weakReference = new WeakReference<>(this);
        return weakReference;
    }

    @SuppressLint("InflateParams")
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        lifecycle = Lifecycle.CREATE;
        if (permissionTools == null) {
            permissionTools = new PermissionTools(this);
        }
        contentView = LayoutInflater.from(getWeakContext().get()).inflate(R.layout.activity_base, null, false);
        setContentView(contentView);
        initBaseView();
        ViewBinder.bind(this, rootView);
        permissionTools.parseAnnotationPermissionsAndRequest(getClass(), new OnPermissionCheckListener() {
            @Override
            public void startCheck(ConfigurationModules modules) {
                if (getContentView().isShowLoading())
                    hint(BaseLoadingView.DisplayMode.loading, "必要权限检测中...", false);
            }

            @Override
            public void result(ConfigurationModules modules, State state) {
                ToastUtils.show(modules.summary + "权限获取失败");
            }

            @Override
            public void onSuccess(List<ConfigurationModules> modulesList) {
                hint(BaseLoadingView.DisplayMode.normal, "", false);
                initView();
                initListener();
            }
        });
    }

    /**
     * 载入框架内需要的View
     */
    private void initBaseView() {
        flContent = f(R.id.base_flContent);
        blvLoading = f(R.id.base_blvLoading);
        baseTitleView = f(R.id.baseTitle);
        titleLine = f(R.id.base_titleLine);
        enter = new AlphaAnimation(0.0f, 1.0f);
        exit = new AlphaAnimation(1.0f, 0.2f);
        enter.setDuration(600);
        exit.setDuration(420);
        boolean isTitleBarShow = isTitleBarShow();
        titleLine.setVisibility(isTitleBarShow && isTitleLineShow() ? View.VISIBLE : View.GONE);
        initTitleBar(isTitleBarShow);
        blvLoading.setRefreshListener(new BaseLoadingView.CallRefresh() {
            @Override
            public void onCallRefresh() {
                callRefresh();
            }
        });
        LayoutModule module = getContentView();
        if (module.getLayout() > 0 || module.getLayoutView() != null) {
            if (module.getLayout() > 0) {
                rootView = LayoutInflater.from(this).inflate(module.getLayout(), null, false);
                flContent.addView(rootView);
            } else {
                flContent.addView(rootView);
            }
        }
        blvLoading.setVisibility(module.isShowLoading() ? View.VISIBLE : View.GONE);
        if (module.isShowLoading()) hint(DisplayMode.loading, "加载中，请稍候...", module.isFloatting());
    }

    private void initTitleBar(boolean isShow) {
        baseTitleView.setVisibility(isShow ? View.VISIBLE : View.GONE);
        if (isShow) {
            if (isEnableLeftToBack()) {
                baseTitleView.setLeftClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        finish();
                    }
                });
            }
            baseTitleView.setTitle(TextUtils.isEmpty(setTitle()) ? "" : setTitle());
        }
    }

    /**
     * cheek your App Permissions
     *
     * @param listener    when permissions callBack
     * @param permissions the permissions with you wanna get,use @see PermissionTools.PermissionManifest
     */
    public void cheekSelfPermission(Map<String, Boolean> permissions, @NonNull OnPermissionCheckListener listener) {
        permissionTools.setPermissions(permissions).checkPermissions(listener);
    }

    public void cheekSelfPermission(String[] permissions, boolean[] forces, @NonNull OnPermissionCheckListener listener) {
        permissionTools.setPermissions(permissions, forces).checkPermissions(listener);
    }

    public void cheekSelfPermission(boolean force, String[] permissions, @NonNull OnPermissionCheckListener listener) {
        permissionTools.setPermission(force, permissions).checkPermissions(listener);
    }

    //cheek your App Permissions --end

    /**
     * findViewById泛型
     */
    private <T extends View> T f(int id) {
        return (T) findViewById(id);
    }

    /**
     * findViewById泛型
     */
    protected <T extends View> T find(int id) {
        return (T) rootView.findViewById(id);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        cheekPermissionWithHandlerDelay(requestCode);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        permissionTools.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    @Override
    protected void onDestroy() {
        lifecycle = Lifecycle.DESTROY;
        weakReference.clear();
        weakReference = null;
        flContent.clearDisappearingChildren();
        flContent.removeAllViews();
        if (contentView instanceof ViewGroup) {
            ((ViewGroup) contentView).removeAllViews();
        }
        contentView = null;
        permissionTools.destroy();
        super.onDestroy();
    }

    @Override
    protected void onResume() {
        super.onResume();
        lifecycle = Lifecycle.RESUME;
    }

    @Override
    protected void onPause() {
        lifecycle = Lifecycle.PAUSE;
        super.onPause();
    }

    @Override
    protected void onStart() {
        lifecycle = Lifecycle.START;
        super.onStart();
    }

    @Override
    protected void onStop() {
        lifecycle = Lifecycle.STOP;
        super.onStop();
    }

    public boolean isStart() {
        return lifecycle == Lifecycle.START;
    }

    public boolean isDestroy() {
        return lifecycle == Lifecycle.DESTROY;
    }

    public boolean isResume() {
        return lifecycle == Lifecycle.RESUME;
    }

    public boolean isPause() {
        return lifecycle == Lifecycle.PAUSE;
    }

    public boolean isStop() {
        return lifecycle == Lifecycle.STOP;
    }

    public boolean isCreate() {
        return lifecycle == Lifecycle.CREATE;
    }

    public static class ResumeHandler extends Handler {

        @Override
        public void handleMessage(Message msg) {
            if (msg.what == MSG_PERMISSION)
                synchronized (this) {
                    WeakReference<BaseActivity> activity = (WeakReference<BaseActivity>) msg.obj;
                    if (activity != null && activity.get() != null) {
                            activity.get().permissionTools.onPermissionActivityResult(msg.arg1);
                    }
                    if (activity != null)
                        activity.clear();
                }
        }
    }

    public void cheekPermissionWithHandlerDelay(int code) {
        if (handler == null) handler = new ResumeHandler();
        handler.removeCallbacksAndMessages(null);
        Message msg = Message.obtain();
        msg.what = MSG_PERMISSION;
        msg.arg1 = code;
        msg.obj = new WeakReference<>(this);
        handler.sendMessageDelayed(msg, 500);
    }
}
